package com.riku.demo.tryagain.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

@Component
@Aspect
public class TryAgainAspect {

    private final Logger log = LoggerFactory.getLogger(TryAgainAspect.class);

    @Autowired
    private ErrorMapper errorMapper;

    @Pointcut("execution(* com.riku.demo.service..*.*(..))")
    public void tryAgainPointCut() {

    }

    @AfterThrowing(pointcut = "tryAgainPointCut()", throwing="ex")
    public void AfterThrowing(JoinPoint joinPoint, Exception ex){
        Class<?> clazz = joinPoint.getTarget().getClass();
        TryAgain clazzAnnotation = clazz.getAnnotation(TryAgain.class);

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        TryAgain methodAnnotation = method.getAnnotation(TryAgain.class);

        if (clazzAnnotation != null || methodAnnotation != null) {
            Map<String,Object> paramMap = new LinkedHashMap<>();
            Object[] paramValues = joinPoint.getArgs();
            for (int i = 0; i < paramValues.length; i++) {
                paramMap.put(paramValues[i].getClass().getName(),paramValues[i]);
            }
            ObjectMapper om = new ObjectMapper();
            String args = null;
            try {
                args = om.writeValueAsString(paramMap);
            } catch (JsonProcessingException e) {
                log.error("try again参数转换异常",e);
                args = "error";
            }

            TryAgainEntity entity = new TryAgainEntity();
            Long id = SnowFlake.getInstance().nextId();
            entity.setId(id.toString());
            entity.setBeanName(clazz.getName());
            entity.setMethodName(method.getName());
            entity.setErrorMessage(ex);
            entity.setArgs(args);
            errorMapper.insert(entity);

        }
    }
}
